home *** CD-ROM | disk | FTP | other *** search
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- NNNNAAAAMMMMEEEE
- pciio_dma: pciio_dmatrans_addr, pciio_dmatrans_list, pciio_dmamap_alloc,
- pciio_dmamap_addr, pciio_dmamap_list, pciio_dmamap_done,
- pciio_dmamap_free, pciio_dma_addr, pciio_dmamap_drain,
- pciio_dmaaddr_drain, pciio_dmalist_drain - manage DMA on PCI bus
-
- SSSSYYYYNNNNOOOOPPPPSSSSIIIISSSS
- ####iiiinnnncccclllluuuuddddeeee <<<<ssssyyyyssss////PPPPCCCCIIII////ppppcccciiiiiiiioooo....hhhh>>>>
-
- iiiiooooppppaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ddddmmmmaaaattttrrrraaaannnnssss____aaaaddddddddrrrr((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- aaaalllleeeennnnlllliiiisssstttt____tttt
- ppppcccciiiiiiiioooo____ddddmmmmaaaattttrrrraaaannnnssss____lllliiiisssstttt((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- aaaalllleeeennnnlllliiiisssstttt____tttt _l_i_s_t,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____aaaalllllllloooocccc((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- ssssiiiizzzzeeee____tttt _m_a_x,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- iiiiooooppppaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____aaaaddddddddrrrr((((
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt _m_a_p,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e))));;;;
-
- aaaalllleeeennnnlllliiiisssstttt____tttt
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____lllliiiisssstttt((((
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt _m_a_p,,,,
- aaaalllleeeennnnlllliiiisssstttt____tttt _l_i_s_t,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))));;;;
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____ddddoooonnnneeee((((ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt _m_a_p))))
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____ffffrrrreeeeeeee((((ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt _m_a_p))))
-
- iiiiooooppppaaaaddddddddrrrr____tttt
- ppppcccciiiiiiiioooo____ddddmmmmaaaa____aaaaddddddddrrrr((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
-
-
-
- PPPPaaaaggggeeee 1111
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- ddddeeeevvvviiiicccceeee____ddddeeeesssscccc____tttt _d_e_s_c,,,,
- iiiiooooppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _s_i_z_e,,,,
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt ****_m_a_p_p,,,,
- uuuunnnnssssiiiiggggnnnneeeedddd _f_l_a_g_s))))
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____ddddrrrraaaaiiiinnnn((((
- ppppcccciiiiiiiioooo____ddddmmmmaaaammmmaaaapppp____tttt ****_m_a_p))))
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ddddmmmmaaaaaaaaddddddddrrrr____ddddrrrraaaaiiiinnnn((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- ppppaaaaddddddddrrrr____tttt _a_d_d_r,,,,
- ssssiiiizzzzeeee____tttt _b_y_t_e_s))))
-
- vvvvooooiiiidddd
- ppppcccciiiiiiiioooo____ddddmmmmaaaalllliiiisssstttt____ddddrrrraaaaiiiinnnn((((
- vvvveeeerrrrtttteeeexxxx____hhhhddddllll____tttt _v_h_d_l,,,,
- aaaalllleeeennnnlllliiiisssstttt____tttt ****_l_i_s_t))))
-
- AAAArrrrgggguuuummmmeeeennnnttttssss
- _a_d_d_r The DMA buffer address in system physical address space.
-
- _d_e_s_c A device descriptor, usually zero.
-
- _f_l_a_g_s
- Attributes of the mapping.
-
- _l_i_s_t An address/length list as prepared by one of the alenlist
- construction functions (see _a_l_e_n_l_i_s_t(D4)).
-
- _m_a_p A dma map as returned by _p_c_i_i_o__d_m_a_m_a_p__a_l_l_o_c().
-
- _m_a_p_p A place to return a map allocated as a side effect of other work;
- must be initialized to zero, or to a map that should be used instead
- of allocating one.
-
- _m_a_x The maximum range of addresses this map will cover at any one time.
-
- _s_i_z_e The size of the mapped buffer in bytes.
-
- _v_h_d_l The device connection point as passed to the _a_t_t_a_c_h() entry
- point.
-
- DDDDEEEESSSSCCCCRRRRIIIIPPPPTTTTIIIIOOOONNNN
- When a device driver wishes to use Direct Memory Access (DMA) to
- communicate with a device, the system needs to have a chance to set up
- any appropriate mapping registers. The work to be done varies with the
- available hardware and with the version of IRIX. The functions described
- here provide an abstract interface to the creation of DMA mapping objects
- that is consistent across most hardware. These functions always do the
-
-
-
- PPPPaaaaggggeeee 2222
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- least possible work given the available hardware.
-
- There are two different models for setting up a DMA map, one simple but
- fallible and the other more general. In both models, the final goal is
- to retrieve an address in PCI bus address space that can be used by a PCI
- device to write into, or read from, system physical memory.
-
- SSSSiiiimmmmpppplllleeee MMMMooooddddeeeellll
- The simple model provides permanent mappings through fixed mapping
- resources that may or may not exist in a given system at a given time.
- _p_c_i_i_o__d_m_a_t_r_a_n_s__a_d_d_r() is the one-stop shopping place for using system
- fixed shareable mapping resources to construct a DMA address. This is
- not always possible. When it is not, the function returns NULL.
-
- _p_c_i_i_o__d_m_a_t_r_a_n_s__l_i_s_t() is similar, but operates on a list of blocks of
- memory and returns a list of blocks in PCI address space.
-
- When they work, these functions allow the driver to set up DMA with the
- fewest complications. Typically the functions always succeed in some
- platforms (those having simple hardware mappings of PCI to memory), and
- always fail in other platforms (where multiple layers of hardware
- mappings must be configured dynamically). However, drivers that use them
- should be coded as if the functions could succeed or fail alternately in
- the same system (which they could).
-
- GGGGeeeennnneeeerrrraaaallll MMMMooooddddeeeellll
- It is not always possible to establish DMA mappings using common shared
- system resources, so the concept of a DMA channel that preallocates
- scarce mapping resources is provided.
-
- Such a channel is allocated using _p_c_i_i_o__d_m_a_m_a_p__a_l_l_o_c(), which is given
- the maximum size to be mapped. _p_c_i_i_o__d_m_a_m_a_p__a_d_d_r() or
- _p_c_i_i_o__d_m_a_m_a_p__l_i_s_t() is then applied to the map to actually establish the
- proper mappings for a DMA target. Given the base address and block size
- of the buffer for DMA (or a list of buffers), the functions hand back the
- base PCI address to use for accessing that buffer (or a list of PCI
- addresses).
-
- _p_c_i_i_o__d_m_a_m_a_p__d_r_a_i_n(), _p_c_i_i_o__d_m_a_a_d_d_r__d_r_a_i_n() or _p_c_i_i_o__d_m_a_l_i_s_t__d_r_a_i_n() are
- used (depending on how the mapping was created) after a device reports it
- has completed DMA, to ensure that all data along the DMA path has in fact
- reached its destination.
-
- When all DMA to a given buffer (or list) is complete, _p_c_i_i_o__d_m_a_m_a_p__d_o_n_e()
- should be called to idle any mapping hardware (and possibly flush out any
- pipes or buffers along the path that might do unexpected things when
- mapping registers are modified). Later, _p_c_i_i_o__d_m_a_m_a_p__a_d_d_r() or
- _p_c_i_i_o__d_m_a_m_a_p__l_i_s_t() can again be called, specifying the same or another
- buffer area.
-
-
-
-
-
-
- PPPPaaaaggggeeee 3333
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- When a driver is completely finished with a DMA channel -- because the
- channel is used only for initialization of the device, because the
- driver's _c_l_o_s_e() entry point is called so it is known that the device
- will be idle for some time, or because the device or the driver is being
- shut down -- the DMA channel resources should be released using
- _p_c_i_i_o__d_m_a_m_a_p__f_r_e_e().
-
- _p_c_i_i_o__d_m_a__a_d_d_r() combines _p_c_i_i_o__d_m_a_t_r_a_n_s__a_d_d_r() and the
- _p_c_i_i_o__d_m_a_m_a_p__a_l_l_o_c() / _p_c_i_i_o__d_m_a_m_a_p__a_d_d_r() facilities; it attempts to do
- the direct translation, and if that fails, allocates a dmamap and
- attempts to map through it. The _m_a_p_p parameter should point to a
- pciio_dmamap_t which has been either set to NULL, or set to a map that
- should be used if one is needed. On return, the value will be cleared if
- the direct translation worked, or set to the map that was used.
-
- DDDDMMMMAAAA AAAAttttttttrrrriiiibbbbuuuutttteeee FFFFllllaaaaggggssss
- The following attributes are specified in the _f_l_a_g_s argument:
-
- PCIIO_FIXED specifies that all DMA translations are done using fixed
- shared resources. The results of those translations remain
- valid permanently, even if the map resource is subsequently
- used to obtain additional mappings. Fixed shared resources
- are not always available.
-
- PCIIO_NOSLEEP
- specifies that any resources that are needed from the system
- are allocated without sleeping. If any resource allocation
- would require the infrastructure to sleep, the service call
- returns a failure code.
-
- PCIIO_INPLACE
- on a list operation requests that the input list be modified
- in place. When this flag is not specified, a new list is
- allocated for the translated addresses. Allocating a new
- list preserves the contents of the input list. However, it
- can take longer, may require sleeping, and may fail
- (especially if PCIIO_NOSLEEP is specified).
-
- PCIIO_DMA_CMD
- specifies that the DMA channel will be used for command-type
- transactions. The channel is set up to optimize short
- transactions with frequent changes of direction. Unless a
- more specific request is made using one of the other flags,
- any prefetch and write-gatherer hardware in the path is
- disabled.
-
- PCIIO_DMA_DATA
- specifies that the DMA channel will be used for data-type
- transactions. The channel is set up to optimize longer
- transfers. Unless a more specific request is made using one
- of the other flags, any prefetch and write-gatherer hardware
- in the path may be enabled.
-
-
-
- PPPPaaaaggggeeee 4444
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- PCIIO_DMA_A64
- indicates that the device is capable of using 64-bit PCI
- addresses for DMA. If this flag is not specified, only DMA
- addresses in the low 4GB of PCI address space can be
- generated. On some systems, 32-bit PCI addresses are a
- limited resource. The map request fails if a 32-bit region
- cannot be allocated.
-
- PCIIO_WRITE_GATHER
- indicates that the device driver believes turning on write-
- gather hardware for this DMA channel is a good thing. The
- flag overrides the write-gather choice from PCIIO_DMA_CMD.
-
- PCIIO_NOWRITE_GATHER
- indicates that the device driver believes turning on write-
- gather hardware for this DMA channel is a bad thing. The
- flag overrides the write gather choice from PCIIO_DMA_DATA.
-
- PCIIO_PREFETCH
- indicates that the device driver believes turning on
- prefetching hardware for this DMA channel is a good thing.
- The flag overrides the prefetch choice from PCIIO_DMA_CMD.
-
- PCIIO_NOPREFETCH
- indicates that the device driver believes turning on
- prefetching hardware for this DMA channel is a bad thing.
- The flag overrides the prefetch settings from PCIIO_DMA_DATA.
-
- PCIIO_BYTE_STREAM
- demands that any byte-swapping hardware along this DMA path
- be organized so that an ordered stream of bytes from the
- device are deposited in order in system memory. This is the
- typical setting for data streams. If this endianness cannot
- be supplied, then the service call fails.
-
- PCIIO_WORD_VALUES
- demands that any byte-swapping hardware along this DMA path
- be initialized so that 32-bit quantities on PCI-bus 32-bit
- boundaries maintain their binary values. This is the typical
- setting for command-type transactions because command words
- exchanged with a little-endian PCI device retain their binary
- values. If this endianness cannot be supplied, then the
- service call fails.
-
- When PCIIO_BYTE_STREAM is used, the bytes of multibyte values embedded in
- input data are found at their original offsets. Multibyte values from
- little-endian devices may require programmed swapping before use.
-
- When PCIIO_WORD_VALUES is used,
-
-
-
-
-
-
- PPPPaaaaggggeeee 5555
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- +o Single bytes in input data are found at the offset the device places
- them, exclusive-or with 3.
-
- +o 16-bit quantities in input data are found at the offset used by the
- device, exclusive-or with 2, and do not need to be byteswapped.
-
- +o 32-bit values are found at the expected offset, and do not need to be
- byteswapped.
-
- +o 64-bit values are found at the expected offset, and their 32-bit
- halves need to be swapped before use.
-
- EEEEXXXXAAAAMMMMPPPPLLLLEEEESSSS
- Here is one way that a driver might make use of dmamap and dmatrans
- calls.
-
- pcifoo_attach(vertex_hdl_t vhdl)
- {
- pciio_dmamap_t command_map;
- iopaddr_t command_dma;
- struct pcifoo_regs *reg_pio;
- struct pcifoo_ring *command_ring;
- ...
- /*
- * This driver has decided to use a dmamap
- * to get to its command rings, which contain
- * things like DMA addresses and counts; we
- * set PCIIO_WORD_VALUES so we don't have to
- * byteswap the 32-bit values.
- *
- * We still have to swap the upper and lower
- * halves of the 64-bit values.
- */
- /* allocate the channel
- */
- command_map = pciio_dmamap_alloc(
- vhdl, 0,
- RINGBYTES,
- PCIIO_DMA_CMD |
- PCIIO_WORD_VALUES);
- command_dma = pciio_dmamap_addr(
- command_map,
- kvtophys(command_ring),
- RINGBYTES);
- /* tell the device where it can find
- * it's command rings.
- */
- reg_pio->command_dma = command_dma;
- ...
- }
- {
- caddr_t data_buffer;
-
-
-
- PPPPaaaaggggeeee 6666
-
-
-
-
-
-
- ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333)))) ppppcccciiiiiiiioooo____ddddmmmmaaaa((((DDDD3333))))
-
-
-
- size_t data_size;
- ...
- data_dma = pciio_dmatrans_addr(
- vhdl, 0,
- kvtophys(data_buffer), data_size,
- PCIIO_DMA_DATA|
- PCIIO_DMA_A64|
- PCIIO_BYTE_STREAM);
- command_ring->data_dma_lo = data_dma & 0xFFFFFFFF;
- command_ring->data_dma_hi = data_dma >> 32;
- command_ring->data_dma_size = data_size;
- command_ring->ready = 1;
- }
-
-
- SSSSEEEEEEEE AAAALLLLSSSSOOOO
- alenlist(D3), pcibr_get_dmatrans_node(D3), pciio(D3), pciio_config(D3),
- pciio_error(D3), pciio_get(D3), pciio_intr(D3), pciio_pio(D3).
-
- NNNNOOOOTTTTEEEE
- Do not point the _m_a_p_p parameter to the _p_c_i_i_o__d_m_a__a_d_d_r() function at your
- only copy of a map pointer, since it will write a NULL through this
- pointer when direct translations work.
-
- In IRIX 6.3, _p_c_i_i_o__d_m_a_t_r_a_n_s__l_i_s_t() is declared and implemented with two
- arguments only, taking no _f_l_a_g_s argument. When porting a driver from
- IRIX 6.3, add a third argument of NULL (or other flag values as desired).
-
- DDDDIIIIAAAAGGGGNNNNOOOOSSSSTTTTIIIICCCCSSSS
- _p_c_i_i_o__d_m_a_t_r_a_n_s__a_d_d_r() returns zero if shared (fixed) resources can not be
- used to construct a valid PCI address that maps to the desired range of
- physical addresses.
-
- _p_c_i_i_o__d_m_a_t_r_a_n_s__l_i_s_t() returns a null pointer if any of the requested
- physical address blocks can not be reached using shared fixed resources,
- or if unable to allocate a return list.
-
- _p_c_i_i_o__d_m_a_m_a_p__a_l_l_o_c() returns a null pointer if resources can not be
- allocated to establish DMA mappings of the requested size, or if the
- parameters are inconsistent.
-
- _p_c_i_i_o__d_m_a_m_a_p__a_d_d_r() returns zero if the specified target address can not
- be mapped using the specified DMA channel. This would usually be due to
- specifying a target block that is outside the previously specified target
- area or is larger than the previously specified maximum mapping size. It
- may also return a null pointer if the DMA channel is currently in use and
- has not been marked idle by a call to _p_c_i_i_o__d_m_a_m_a_p__d_o_n_e().
-
- _p_c_i_i_o__d_m_a_m_a_p__l_i_s_t() can return a null pointer for all the reasons
- mentioned above, or if it is unable to allocate the return list.
-
-
-
-
-
- PPPPaaaaggggeeee 7777
-
-
-
-